﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace SpaceGame.Gameplay.AI.Behaviors
{

    /// <summary>
    /// Behavior responsible for seeking enemy and attacking.
    /// </summary>
    public class AttackBehavior : Behavior
    {
        /// <summary>
        /// 
        /// </summary>
        private const float minDistanceEnemySquared = 40000;

        /// <summary>
        /// 
        /// </summary>
        public Ship NearestEnemy 
        {
            get; private set;
        }

        /// <summary>
        /// 
        /// </summary>
        public bool IsEnemyClose 
        { 
            get; private set;
        }

        /// <summary>
        /// 
        /// </summary>
        public Ship VisibleEnemy
        {
            get; private set;
        }

        /// <summary>
        /// 
        /// </summary>
        public Vector2 AimAtVisibleEnemy
        {
            get
            {
                if(VisibleEnemy != null)
                {
                    //add noise to make aim more human
                    var target = VisibleEnemy.Position;
                    target.X += ((float)random.NextDouble() * random.Next(150));
                    target.Y += ((float)random.NextDouble() * random.Next(150));

                    return target - Entity.Position;
                }

                return Vector2.Zero;
            }
        }

        public AttackBehavior(IEntity ship)
            : base(ship)
        {
        }

        
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool CheckForVisibleEnemy()
        {
            //find nearest enemy
            var q = from ship in Entity.World.Ships
                    let distance = Vector2.DistanceSquared(ship.Position, Entity.Position)
                    orderby distance descending
                    where !ship.Dead && ship != Entity && Entity.World.IsInLineOfSight(Entity, ship)
                    select ship;

            var visible = q.FirstOrDefault();
            if (visible == null)
            {
                VisibleEnemy = null;
                return false;
            }

            VisibleEnemy = visible;
            return true;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool CheckForNearestEnemy()
        {
            //find nearest enemy
            var q = from ship in Entity.World.Ships
                    let distance = Vector2.DistanceSquared(ship.Position, Entity.Position)
                    orderby distance descending
                    where !ship.Dead && ship != Entity
                    select new { ship, distance };

            var nearest = q.FirstOrDefault();
            if (nearest == null)
            {
                IsEnemyClose = false;
                NearestEnemy = null;
                return false;
            }

            NearestEnemy = nearest.ship;
            IsEnemyClose = nearest.distance < minDistanceEnemySquared;

            return true;

        }
    }
}
